import { Command } from '@/commands/command.ts'
import { BaseCommand } from '@/commands/commands/base.ts'
import { AiCommand } from '@/commands/commands/ai.ts'
import { DatetimeCommand } from '@/commands/commands/datetime.ts'
import { HmacCommand } from '@/commands/commands/hmac.ts'
import { LengthCommand } from '@/commands/commands/length.ts'
import { Md5Command } from '@/commands/commands/md5.ts'
import { QrCodeCommand } from '@/commands/commands/qrcode.ts'
import { RandStrCommand } from '@/commands/commands/rand_str.ts'
import { ShaCommand } from '@/commands/commands/sha.ts'
import { TimestampCommand } from '@/commands/commands/timestamp.ts'
import { CalcCommand } from '@/commands/commands/calc.ts'
import { JsonCommand } from '@/commands/commands/json.ts'
import { SearchCommand } from '@/commands/commands/search.ts'
import { IpCommand } from '@/commands/commands/ip.ts'
import { UrlCommand } from '@/commands/commands/url.ts'
import { NanoidCommand } from '@/commands/commands/nanoid.ts'

export const factors: Record<string, (args: string) => Command> = {
    ai: (args: string) => AiCommand.new(args),
    base: (args: string) => BaseCommand.new(args),
    datetime: (args: string) => DatetimeCommand.new(args),
    hmac: (args: string) => HmacCommand.new(args),
    length: (args: string) => LengthCommand.new(args),
    md5: (args: string) => Md5Command.new(args),
    qrcode: (args: string) => QrCodeCommand.new(args),
    randstr: (args: string) => RandStrCommand.new(args),
    sha: (args: string) => ShaCommand.new(args),
    timestamp: (args: string) => TimestampCommand.new(args),
    calc: (args: string) => CalcCommand.new(args),
    json: (args: string) => JsonCommand.new(args),
    search: (args: string) => SearchCommand.new(args),
    ip: (args: string) => IpCommand.new(args),
    url: (args: string) => UrlCommand.new(args),
    nanoid: (args: string) => NanoidCommand.new(args),
}

export function new_command(input: string, default_command: string = 'ai', default_args: string = ''): Command | null {
    const tokens = input.split(' ')

    {
        const factor = factors[tokens[0]]
        if (undefined !== factor && null !== factor) {
            return factor(input)
        }
    }

    {
        const factor = factors[default_command]
        if (undefined !== factor && null !== factor) {
            return factor(default_command + ' ' + default_args + ' ' + input)
        }
    }

    return null
}

/**
 * 返回给定输入的建议命令
 * @param input
 */
export function command_suggestions(input: string): string[] {
    const tokens = input.split(' ')
    if (0 === tokens.length || '' === tokens[0]) {
        return []
    }

    const result: string[] = []
    for (const command of Object.keys(factors)) {
        if (command.startsWith(tokens[0])) {
            // 处理命令别名
            let usage = factors[command]('').usage()

            const tokens = usage.split(' ')
            tokens[0] = command

            result.push(tokens.join(' '))
        }
    }

    return result
}
